package edu.umd.cs.mouseprecision;

import java.awt.Color;

import edu.umd.cs.piccolo.event.PBasicInputEventHandler;
import edu.umd.cs.piccolo.event.PInputEvent;
import edu.umd.cs.piccolox.nodes.PLine;

public class MousePath extends PLine {
	
	private TaskCanvas parentCanvas;
	
	private TaskCanvas.TaskType taskType;
	
	
	public MousePath(TaskCanvas parentCanvas, TaskCanvas.TaskType taskType){
		
		this.parentCanvas = parentCanvas;
		this.taskType = taskType;
		
		//scale of the path
		this.setScale(Main.SCALE);
		
		//generates all points
		generatePoints();
		
		//event listeners for mouse inside/outside path
		this.addInputEventListener(
				new PBasicInputEventHandler() {
					
					public void mouseEntered(PInputEvent event){
						setMouseInside(true);
						}
					public void mouseExited(PInputEvent event){
						setMouseInside(false);
						}
				}
			);
	}


	private void generatePoints() {
		
		float[] hsbColor = Color.RGBtoHSB(0, 0, 0, null);
		this.setStrokePaint(Color.getHSBColor(hsbColor[0], hsbColor[1], hsbColor[2]));
		int i =0;
		switch(taskType){
			case TRAIN:
				this.addPoint(i++,2*Main.RASTER, 2*Main.RASTER);
				this.addPoint(i++,3*Main.RASTER, 2*Main.RASTER);
				this.addPoint(i++,3*Main.RASTER, 3*Main.RASTER);
				this.addPoint(i++,4*Main.RASTER, 4*Main.RASTER);
				this.addPoint(i++,5*Main.RASTER, 3*Main.RASTER);
				for(double j = 0.0; j<=2*Math.PI;j=j+0.1){
					this.addPoint(i++,0.5*j*Main.RASTER+(5*Main.RASTER), -1.0* 0.8* Math.sin(j)*Main.RASTER+3*Main.RASTER);
				}
				
				break;
			case SQUARE:
				this.addPoint(i++,3*Main.RASTER, 1*Main.RASTER);
				this.addPoint(i++,3*Main.RASTER, 2*Main.RASTER);
				this.addPoint(i++,2*Main.RASTER, 2*Main.RASTER);
				this.addPoint(i++,2*Main.RASTER, 3*Main.RASTER);
				this.addPoint(i++,1*Main.RASTER, 3*Main.RASTER);
				this.addPoint(i++,1*Main.RASTER, 4*Main.RASTER);
				this.addPoint(i++,2*Main.RASTER, 4*Main.RASTER);
				this.addPoint(i++,2*Main.RASTER, 5*Main.RASTER);
				this.addPoint(i++,3*Main.RASTER, 5*Main.RASTER);
				this.addPoint(i++,3*Main.RASTER, 4*Main.RASTER);
				this.addPoint(i++,4*Main.RASTER, 4*Main.RASTER);
				//the two diagonal pieces
				this.addPoint(i++,5*Main.RASTER, 3*Main.RASTER);
				this.addPoint(i++,6*Main.RASTER, 4*Main.RASTER);
								
				this.addPoint(i++,6*Main.RASTER, 5*Main.RASTER);
				this.addPoint(i++,7*Main.RASTER, 5*Main.RASTER);
				this.addPoint(i++,7*Main.RASTER, 4*Main.RASTER);
				this.addPoint(i++,8*Main.RASTER, 4*Main.RASTER);
				this.addPoint(i++,8*Main.RASTER, 3*Main.RASTER);
				this.addPoint(i++,7*Main.RASTER, 3*Main.RASTER);
				this.addPoint(i++,7*Main.RASTER, 2*Main.RASTER);
				this.addPoint(i++,6*Main.RASTER, 2*Main.RASTER);
				this.addPoint(i++,6*Main.RASTER, 1*Main.RASTER);
				this.addPoint(i++,5*Main.RASTER, 1*Main.RASTER);
				break;
			case DIAGONAL:
				double s = Math.sqrt(2.0);
				this.addPoint(i++,1*Main.RASTER, 1*Main.RASTER);
				this.addPoint(i++,(1+s/2.0)*Main.RASTER, (1+s/2.0)*Main.RASTER);
				this.addPoint(i++,(1+s)*Main.RASTER, 1*Main.RASTER);
				this.addPoint(i++,(1+s+s/2.0)*Main.RASTER, (1+s/2.0)*Main.RASTER);
				this.addPoint(i++,(1+2*s)*Main.RASTER, 1*Main.RASTER);
				this.addPoint(i++,(1+2*s+s/2.0)*Main.RASTER, (1+s/2.0)*Main.RASTER);
				this.addPoint(i++,(1+3*s)*Main.RASTER, 1*Main.RASTER);
				this.addPoint(i++,(1+3*s+s/2.0)*Main.RASTER, (1+s/2.0)*Main.RASTER);
				this.addPoint(i++,(1+4*s)*Main.RASTER, 1*Main.RASTER);
				this.addPoint(i++,(1+4*s+s/2.0)*Main.RASTER, (1+s/2.0)*Main.RASTER);
				this.addPoint(i++,(1+5*s)*Main.RASTER, 1*Main.RASTER);
				//the vertical bar
				this.addPoint(i++,(1+5*s)*Main.RASTER, 3*Main.RASTER);
				
				this.addPoint(i++,(1+4*s+s/2.0)*Main.RASTER, (3-s/2.0)*Main.RASTER);
				this.addPoint(i++,(1+4*s)*Main.RASTER, 3*Main.RASTER);
				this.addPoint(i++,(1+3*s+s/2.0)*Main.RASTER, (3-s/2.0)*Main.RASTER);
				this.addPoint(i++,(1+3*s)*Main.RASTER, 3*Main.RASTER);
				this.addPoint(i++,(1+2*s+s/2.0)*Main.RASTER, (3-s/2.0)*Main.RASTER);
				this.addPoint(i++,(1+2*s)*Main.RASTER, 3*Main.RASTER);
				this.addPoint(i++,(1+s+s/2.0)*Main.RASTER, (3-s/2.0)*Main.RASTER);
				this.addPoint(i++,(1+s)*Main.RASTER, 3*Main.RASTER);
				this.addPoint(i++,(1+s/2.0)*Main.RASTER, (3-s/2.0)*Main.RASTER);
				this.addPoint(i++,1*Main.RASTER, 3*Main.RASTER);
				break;
			case ROUND:
				for(double j = 0.0; j<=5.5*Math.PI;j=j+0.1){
					this.addPoint(i++,0.5*j*Main.RASTER+(1*Main.RASTER), -1.0* 0.8* Math.sin(j)*Main.RASTER+1.5*Main.RASTER);
				}
				
				for(double j = 5.5*Math.PI; j>0.0;j=j-0.1){
					this.addPoint(i++,0.5*j*Main.RASTER+(1*Main.RASTER), +1.0* 0.8 * Math.sin(j)*Main.RASTER+3.5*Main.RASTER);
				}
				break;
		}
	}


	private void setMouseInside(boolean inside) {
		parentCanvas.setMouseInside(inside);		
	}


	public double[] getPositionForStartArea() {
		switch(taskType){
			case TRAIN:
				return new double[]{1*Main.RASTER, 1.5*Main.RASTER};
			case SQUARE:
				return new double[]{2.5*Main.RASTER, 0.0*Main.RASTER};
			case DIAGONAL:
				return new double[]{0.0*Main.RASTER, 0.5*Main.RASTER};
			case ROUND:
				return new double[]{0.0*Main.RASTER, 1.0*Main.RASTER};
		}
		return new double[]{0.0,0.0};
	}


	public double[] getPositionForFinishArea() {
		switch(taskType){
			case TRAIN:
				return new double[]{Math.PI*Main.RASTER+5*Main.RASTER, 2.0*Main.RASTER};
			case SQUARE:
				return new double[]{4*Main.RASTER, 0.5*Main.RASTER};
			case DIAGONAL:
				return new double[]{0.0*Main.RASTER, 2.5*Main.RASTER};
			case ROUND:
				return new double[]{0.0*Main.RASTER, 3.0*Main.RASTER};
		}
		return new double[]{0.0,0.0};
		
		
		
	}
}
